Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix link to file url behavior with trailingSlash #14681

Merged
merged 6 commits into from
Jun 30, 2020

Conversation

Janpot
Copy link
Contributor

@Janpot Janpot commented Jun 29, 2020

Avoid trailing slashes on urls that look like files. The redirect for trailingSlash: true will now look like:

Redirects

┌ source: /:path*/:file.:ext/
├ destination: /:path*/:file.:ext
└ permanent: true

┌ source: /:path*/:notfile([^/.]+)
├ destination: /:path*/:notfile/
└ permanent: true

The default still looks like:

Redirects

┌ source: /:path+/
├ destination: /:path+
└ permanent: true

After this gets merged, I have a few optimizations planned on the normalization code that should reduce the client bundle a little and that consolidates the trailingSlash and exportTrailingSlash options

@ijjk
Copy link
Member

ijjk commented Jun 29, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
buildDuration 12.6s 12.6s ⚠️ +58ms
nodeModulesSize 67.1 MB 67.1 MB ⚠️ +978 B
Page Load Tests Overall increase ✓
vercel/next.js canary Janpot/next.js trailing-slash-files Change
/ failed reqs 0 0
/ total time (seconds) 2.086 2.076 -0.01
/ avg req/sec 1198.56 1204.09 +5.53
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.275 1.271 0
/error-in-render avg req/sec 1960.98 1967.03 +6.05
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
main-HASH.js gzip 6.59 kB 6.59 kB
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..2b0d.js gzip 10.6 kB 10.6 kB ⚠️ +17 B
framework.HASH.js gzip 39.1 kB 39.1 kB
Overall change 57.1 kB 57.1 kB ⚠️ +17 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
main-HASH.module.js gzip 5.68 kB 5.68 kB
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.03 kB 7.05 kB ⚠️ +20 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
Overall change 52.6 kB 52.6 kB ⚠️ +20 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js trailing-slash-files Change
polyfills-HASH.js gzip 26.3 kB 26.3 kB
Overall change 26.3 kB 26.3 kB
Client Build Manifests
vercel/next.js canary Janpot/next.js trailing-slash-files Change
_buildManifest.js gzip 268 B 268 B
_buildManife..dule.js gzip 272 B 272 B
Overall change 540 B 540 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
index.html gzip 955 B 955 B
link.html gzip 960 B 960 B
withRouter.html gzip 946 B 947 B ⚠️ +1 B
Overall change 2.86 kB 2.86 kB ⚠️ +1 B

Diffs

Diff for 19b7e98f51cc..975a5c6b4.js
@@ -246,12 +246,20 @@
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
 
       function normalizeTrailingSlash(path, requireSlash) {
-        if (path === "/") {
-          return path;
-        } else if (path.endsWith("/")) {
-          return requireSlash ? path : path.slice(0, -1);
+        if (requireSlash) {
+          if (!path.endsWith("/") && !/\.[^/]+$/.test(path)) {
+            return path + "/";
+          } else if (/\.[^/]+\/$/.test(path)) {
+            return path.slice(0, -1);
+          } else {
+            return path;
+          }
         } else {
-          return requireSlash ? path + "/" : path;
+          if (path.endsWith("/") && path !== "/") {
+            return path.slice(0, -1);
+          } else {
+            return path;
+          }
         }
       }
Diff for 19b7e98f51cc..1b.module.js
@@ -223,12 +223,20 @@
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
 
       function normalizeTrailingSlash(path, requireSlash) {
-        if (path === "/") {
-          return path;
-        } else if (path.endsWith("/")) {
-          return requireSlash ? path : path.slice(0, -1);
+        if (requireSlash) {
+          if (!path.endsWith("/") && !/\.[^/]+$/.test(path)) {
+            return path + "/";
+          } else if (/\.[^/]+\/$/.test(path)) {
+            return path.slice(0, -1);
+          } else {
+            return path;
+          }
         } else {
-          return requireSlash ? path + "/" : path;
+          if (path.endsWith("/") && path !== "/") {
+            return path.slice(0, -1);
+          } else {
+            return path;
+          }
         }
       }
Diff for index.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.a6c8b8b5bb69078be31b.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.43ca65d7fdbd89ddb0ae.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.284ee6bd3fa975a5c6b4.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.95470164c1780a50d1d3.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.a6c8b8b5bb69078be31b.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.43ca65d7fdbd89ddb0ae.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.a6c8b8b5bb69078be31b.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.43ca65d7fdbd89ddb0ae.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.284ee6bd3fa975a5c6b4.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.95470164c1780a50d1d3.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.a6c8b8b5bb69078be31b.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.43ca65d7fdbd89ddb0ae.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.a6c8b8b5bb69078be31b.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.43ca65d7fdbd89ddb0ae.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.284ee6bd3fa975a5c6b4.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.95470164c1780a50d1d3.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.a6c8b8b5bb69078be31b.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.43ca65d7fdbd89ddb0ae.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
buildDuration 13.3s 13.6s ⚠️ +273ms
nodeModulesSize 67.1 MB 67.1 MB ⚠️ +978 B
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
main-HASH.js gzip 6.59 kB 6.59 kB
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..2b0d.js gzip 10.6 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..c0a1.js gzip N/A 10.6 kB N/A
Overall change 57.1 kB 57.1 kB ⚠️ +17 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
main-HASH.module.js gzip 5.68 kB 5.68 kB
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.03 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..dule.js gzip N/A 7.05 kB N/A
Overall change 52.6 kB 52.6 kB ⚠️ +20 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js trailing-slash-files Change
polyfills-HASH.js gzip 26.3 kB 26.3 kB
Overall change 26.3 kB 26.3 kB
Client Build Manifests
vercel/next.js canary Janpot/next.js trailing-slash-files Change
_buildManifest.js gzip 268 B 268 B
_buildManife..dule.js gzip 272 B 272 B
Overall change 540 B 540 B
Serverless bundles Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
_error.js 875 kB 875 kB
404.html 4.17 kB 4.17 kB
hooks.html 3.79 kB 3.79 kB
index.js 876 kB 876 kB
link.js 915 kB 915 kB ⚠️ +161 B
routerDirect.js 907 kB 907 kB ⚠️ +161 B
withRouter.js 907 kB 907 kB ⚠️ +161 B
Overall change 4.49 MB 4.49 MB ⚠️ +483 B
Commit: dc0c7aa

@ijjk
Copy link
Member

ijjk commented Jun 29, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
buildDuration 12.7s 12.6s -53ms
nodeModulesSize 67.1 MB 67.1 MB ⚠️ +978 B
Page Load Tests Overall decrease ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
/ failed reqs 0 0
/ total time (seconds) 2.226 2.212 -0.01
/ avg req/sec 1123.18 1130.26 +7.08
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.475 1.538 ⚠️ +0.06
/error-in-render avg req/sec 1694.66 1625.27 ⚠️ -69.39
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
main-HASH.js gzip 6.59 kB 6.59 kB
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..2b0d.js gzip 10.6 kB 10.6 kB ⚠️ +17 B
framework.HASH.js gzip 39.1 kB 39.1 kB
Overall change 57.1 kB 57.1 kB ⚠️ +17 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
main-HASH.module.js gzip 5.68 kB 5.68 kB
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.03 kB 7.05 kB ⚠️ +20 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
Overall change 52.6 kB 52.6 kB ⚠️ +20 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js trailing-slash-files Change
polyfills-HASH.js gzip 26.3 kB 26.3 kB
Overall change 26.3 kB 26.3 kB
Client Build Manifests
vercel/next.js canary Janpot/next.js trailing-slash-files Change
_buildManifest.js gzip 268 B 268 B
_buildManife..dule.js gzip 272 B 272 B
Overall change 540 B 540 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
index.html gzip 955 B 955 B
link.html gzip 960 B 960 B
withRouter.html gzip 946 B 947 B ⚠️ +1 B
Overall change 2.86 kB 2.86 kB ⚠️ +1 B

Diffs

Diff for 19b7e98f51cc..975a5c6b4.js
@@ -246,12 +246,20 @@
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
 
       function normalizeTrailingSlash(path, requireSlash) {
-        if (path === "/") {
-          return path;
-        } else if (path.endsWith("/")) {
-          return requireSlash ? path : path.slice(0, -1);
+        if (requireSlash) {
+          if (!path.endsWith("/") && !/\.[^/]+$/.test(path)) {
+            return path + "/";
+          } else if (/\.[^/]+\/$/.test(path)) {
+            return path.slice(0, -1);
+          } else {
+            return path;
+          }
         } else {
-          return requireSlash ? path + "/" : path;
+          if (path.endsWith("/") && path !== "/") {
+            return path.slice(0, -1);
+          } else {
+            return path;
+          }
         }
       }
Diff for 19b7e98f51cc..1b.module.js
@@ -223,12 +223,20 @@
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
 
       function normalizeTrailingSlash(path, requireSlash) {
-        if (path === "/") {
-          return path;
-        } else if (path.endsWith("/")) {
-          return requireSlash ? path : path.slice(0, -1);
+        if (requireSlash) {
+          if (!path.endsWith("/") && !/\.[^/]+$/.test(path)) {
+            return path + "/";
+          } else if (/\.[^/]+\/$/.test(path)) {
+            return path.slice(0, -1);
+          } else {
+            return path;
+          }
         } else {
-          return requireSlash ? path + "/" : path;
+          if (path.endsWith("/") && path !== "/") {
+            return path.slice(0, -1);
+          } else {
+            return path;
+          }
         }
       }
Diff for index.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.a6c8b8b5bb69078be31b.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.43ca65d7fdbd89ddb0ae.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.284ee6bd3fa975a5c6b4.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.95470164c1780a50d1d3.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.a6c8b8b5bb69078be31b.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.43ca65d7fdbd89ddb0ae.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.a6c8b8b5bb69078be31b.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.43ca65d7fdbd89ddb0ae.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.284ee6bd3fa975a5c6b4.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.95470164c1780a50d1d3.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.a6c8b8b5bb69078be31b.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.43ca65d7fdbd89ddb0ae.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.a6c8b8b5bb69078be31b.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.43ca65d7fdbd89ddb0ae.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.284ee6bd3fa975a5c6b4.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.95470164c1780a50d1d3.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.a6c8b8b5bb69078be31b.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.43ca65d7fdbd89ddb0ae.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
buildDuration 13.3s 13.7s ⚠️ +453ms
nodeModulesSize 67.1 MB 67.1 MB ⚠️ +978 B
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
main-HASH.js gzip 6.59 kB 6.59 kB
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..2b0d.js gzip 10.6 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..c0a1.js gzip N/A 10.6 kB N/A
Overall change 57.1 kB 57.1 kB ⚠️ +17 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
main-HASH.module.js gzip 5.68 kB 5.68 kB
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.03 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..dule.js gzip N/A 7.05 kB N/A
Overall change 52.6 kB 52.6 kB ⚠️ +20 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js trailing-slash-files Change
polyfills-HASH.js gzip 26.3 kB 26.3 kB
Overall change 26.3 kB 26.3 kB
Client Build Manifests
vercel/next.js canary Janpot/next.js trailing-slash-files Change
_buildManifest.js gzip 268 B 268 B
_buildManife..dule.js gzip 272 B 272 B
Overall change 540 B 540 B
Serverless bundles Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
_error.js 875 kB 875 kB
404.html 4.17 kB 4.17 kB
hooks.html 3.79 kB 3.79 kB
index.js 876 kB 876 kB
link.js 915 kB 915 kB ⚠️ +161 B
routerDirect.js 907 kB 907 kB ⚠️ +161 B
withRouter.js 907 kB 907 kB ⚠️ +161 B
Overall change 4.49 MB 4.49 MB ⚠️ +483 B
Commit: a152267

@Janpot Janpot changed the title Fix file behavior and trailingSlash Fix link to file url behavior with trailingSlash Jun 29, 2020
Copy link
Contributor

@dav-is dav-is left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great 👍

@ijjk
Copy link
Member

ijjk commented Jun 29, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
buildDuration 10.8s 10.5s -270ms
nodeModulesSize 66 MB 66 MB ⚠️ +978 B
Page Load Tests Overall decrease ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
/ failed reqs 0 0
/ total time (seconds) 1.8 1.774 -0.03
/ avg req/sec 1388.91 1409.52 +20.61
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.05 1.073 ⚠️ +0.02
/error-in-render avg req/sec 2380.81 2330.54 ⚠️ -50.27
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
main-HASH.js gzip 6.59 kB 6.59 kB
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..65e3.js gzip 10.7 kB 10.7 kB ⚠️ +17 B
framework.HASH.js gzip 39.1 kB 39.1 kB
Overall change 57.2 kB 57.2 kB ⚠️ +17 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
main-HASH.module.js gzip 5.68 kB 5.68 kB
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.08 kB 7.1 kB ⚠️ +18 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
Overall change 52.7 kB 52.7 kB ⚠️ +18 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js trailing-slash-files Change
polyfills-HASH.js gzip 26.3 kB 26.3 kB
Overall change 26.3 kB 26.3 kB
Client Build Manifests
vercel/next.js canary Janpot/next.js trailing-slash-files Change
_buildManifest.js gzip 268 B 268 B
_buildManife..dule.js gzip 272 B 272 B
Overall change 540 B 540 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
index.html gzip 954 B 955 B ⚠️ +1 B
link.html gzip 959 B 960 B ⚠️ +1 B
withRouter.html gzip 946 B 947 B ⚠️ +1 B
Overall change 2.86 kB 2.86 kB ⚠️ +3 B

Diffs

Diff for 19b7e98f51cc..15.module.js
@@ -223,12 +223,20 @@
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
 
       function normalizeTrailingSlash(path, requireSlash) {
-        if (path === "/") {
-          return path;
-        } else if (path.endsWith("/")) {
-          return requireSlash ? path : path.slice(0, -1);
+        if (requireSlash) {
+          if (!path.endsWith("/") && !/\.[^/]+$/.test(path)) {
+            return path + "/";
+          } else if (/\.[^/]+\/$/.test(path)) {
+            return path.slice(0, -1);
+          } else {
+            return path;
+          }
         } else {
-          return requireSlash ? path + "/" : path;
+          if (path.endsWith("/") && path !== "/") {
+            return path.slice(0, -1);
+          } else {
+            return path;
+          }
         }
       }
Diff for 19b7e98f51cc..87e3a8a17.js
@@ -246,12 +246,20 @@
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
 
       function normalizeTrailingSlash(path, requireSlash) {
-        if (path === "/") {
-          return path;
-        } else if (path.endsWith("/")) {
-          return requireSlash ? path : path.slice(0, -1);
+        if (requireSlash) {
+          if (!path.endsWith("/") && !/\.[^/]+$/.test(path)) {
+            return path + "/";
+          } else if (/\.[^/]+\/$/.test(path)) {
+            return path.slice(0, -1);
+          } else {
+            return path;
+          }
         } else {
-          return requireSlash ? path + "/" : path;
+          if (path.endsWith("/") && path !== "/") {
+            return path.slice(0, -1);
+          } else {
+            return path;
+          }
         }
       }
Diff for index.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.1d2db78faa222df2e115.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.3cb7725cf3999f7cc051.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.d4b5787347787e3a8a17.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.aa65cd9800fdeb72a474.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.1d2db78faa222df2e115.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.3cb7725cf3999f7cc051.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.1d2db78faa222df2e115.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.3cb7725cf3999f7cc051.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.d4b5787347787e3a8a17.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.aa65cd9800fdeb72a474.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.1d2db78faa222df2e115.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.3cb7725cf3999f7cc051.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.1d2db78faa222df2e115.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.3cb7725cf3999f7cc051.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.d4b5787347787e3a8a17.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.aa65cd9800fdeb72a474.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.1d2db78faa222df2e115.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.3cb7725cf3999f7cc051.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
buildDuration 11.4s 11.7s ⚠️ +296ms
nodeModulesSize 66 MB 66 MB ⚠️ +978 B
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
main-HASH.js gzip 6.59 kB 6.59 kB
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..65e3.js gzip 10.7 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..dde9.js gzip N/A 10.7 kB N/A
Overall change 57.2 kB 57.2 kB ⚠️ +17 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
main-HASH.module.js gzip 5.68 kB 5.68 kB
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.08 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..dule.js gzip N/A 7.1 kB N/A
Overall change 52.7 kB 52.7 kB ⚠️ +18 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js trailing-slash-files Change
polyfills-HASH.js gzip 26.3 kB 26.3 kB
Overall change 26.3 kB 26.3 kB
Client Build Manifests
vercel/next.js canary Janpot/next.js trailing-slash-files Change
_buildManifest.js gzip 268 B 268 B
_buildManife..dule.js gzip 272 B 272 B
Overall change 540 B 540 B
Serverless bundles Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
_error.js 875 kB 875 kB
404.html 4.17 kB 4.17 kB
hooks.html 3.79 kB 3.79 kB
index.js 876 kB 876 kB
link.js 915 kB 915 kB ⚠️ +161 B
routerDirect.js 907 kB 907 kB ⚠️ +161 B
withRouter.js 907 kB 907 kB ⚠️ +161 B
Overall change 4.49 MB 4.49 MB ⚠️ +483 B
Commit: 181dea0

@ijjk
Copy link
Member

ijjk commented Jun 30, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
buildDuration 13.5s 13.4s -131ms
nodeModulesSize 66 MB 66 MB ⚠️ +978 B
Page Load Tests Overall increase ✓
vercel/next.js canary Janpot/next.js trailing-slash-files Change
/ failed reqs 0 0
/ total time (seconds) 2.341 2.349 ⚠️ +0.01
/ avg req/sec 1067.83 1064.3 ⚠️ -3.53
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.57 1.531 -0.04
/error-in-render avg req/sec 1592.48 1633.39 +40.91
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
main-HASH.js gzip 6.59 kB 6.59 kB
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..65e3.js gzip 10.7 kB 10.7 kB ⚠️ +17 B
framework.HASH.js gzip 39.1 kB 39.1 kB
Overall change 57.2 kB 57.2 kB ⚠️ +17 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
main-HASH.module.js gzip 5.68 kB 5.68 kB
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.08 kB 7.1 kB ⚠️ +18 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
Overall change 52.7 kB 52.7 kB ⚠️ +18 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js trailing-slash-files Change
polyfills-HASH.js gzip 26.3 kB 26.3 kB
Overall change 26.3 kB 26.3 kB
Client Build Manifests
vercel/next.js canary Janpot/next.js trailing-slash-files Change
_buildManifest.js gzip 268 B 268 B
_buildManife..dule.js gzip 272 B 272 B
Overall change 540 B 540 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
index.html gzip 951 B 953 B ⚠️ +2 B
link.html gzip 956 B 956 B
withRouter.html gzip 944 B 944 B
Overall change 2.85 kB 2.85 kB ⚠️ +2 B

Diffs

Diff for 19b7e98f51cc..15.module.js
@@ -223,12 +223,20 @@
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
 
       function normalizeTrailingSlash(path, requireSlash) {
-        if (path === "/") {
-          return path;
-        } else if (path.endsWith("/")) {
-          return requireSlash ? path : path.slice(0, -1);
+        if (requireSlash) {
+          if (!path.endsWith("/") && !/\.[^/]+$/.test(path)) {
+            return path + "/";
+          } else if (/\.[^/]+\/$/.test(path)) {
+            return path.slice(0, -1);
+          } else {
+            return path;
+          }
         } else {
-          return requireSlash ? path + "/" : path;
+          if (path.endsWith("/") && path !== "/") {
+            return path.slice(0, -1);
+          } else {
+            return path;
+          }
         }
       }
Diff for 19b7e98f51cc..87e3a8a17.js
@@ -246,12 +246,20 @@
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
 
       function normalizeTrailingSlash(path, requireSlash) {
-        if (path === "/") {
-          return path;
-        } else if (path.endsWith("/")) {
-          return requireSlash ? path : path.slice(0, -1);
+        if (requireSlash) {
+          if (!path.endsWith("/") && !/\.[^/]+$/.test(path)) {
+            return path + "/";
+          } else if (/\.[^/]+\/$/.test(path)) {
+            return path.slice(0, -1);
+          } else {
+            return path;
+          }
         } else {
-          return requireSlash ? path + "/" : path;
+          if (path.endsWith("/") && path !== "/") {
+            return path.slice(0, -1);
+          } else {
+            return path;
+          }
         }
       }
Diff for index.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.1d2db78faa222df2e115.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.3cb7725cf3999f7cc051.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.d4b5787347787e3a8a17.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.aa65cd9800fdeb72a474.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.1d2db78faa222df2e115.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.3cb7725cf3999f7cc051.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.1d2db78faa222df2e115.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.3cb7725cf3999f7cc051.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.d4b5787347787e3a8a17.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.aa65cd9800fdeb72a474.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.1d2db78faa222df2e115.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.3cb7725cf3999f7cc051.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.1d2db78faa222df2e115.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.3cb7725cf3999f7cc051.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.d4b5787347787e3a8a17.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.aa65cd9800fdeb72a474.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.1d2db78faa222df2e115.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.3cb7725cf3999f7cc051.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
buildDuration 14.2s 14.5s ⚠️ +327ms
nodeModulesSize 66 MB 66 MB ⚠️ +978 B
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
main-HASH.js gzip 6.59 kB 6.59 kB
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..65e3.js gzip 10.7 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..dde9.js gzip N/A 10.7 kB N/A
Overall change 57.2 kB 57.2 kB ⚠️ +17 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
main-HASH.module.js gzip 5.68 kB 5.68 kB
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.08 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..dule.js gzip N/A 7.1 kB N/A
Overall change 52.7 kB 52.7 kB ⚠️ +18 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js trailing-slash-files Change
polyfills-HASH.js gzip 26.3 kB 26.3 kB
Overall change 26.3 kB 26.3 kB
Client Build Manifests
vercel/next.js canary Janpot/next.js trailing-slash-files Change
_buildManifest.js gzip 268 B 268 B
_buildManife..dule.js gzip 272 B 272 B
Overall change 540 B 540 B
Serverless bundles Overall increase ⚠️
vercel/next.js canary Janpot/next.js trailing-slash-files Change
_error.js 875 kB 875 kB
404.html 4.17 kB 4.17 kB
hooks.html 3.79 kB 3.79 kB
index.js 876 kB 876 kB
link.js 915 kB 915 kB ⚠️ +161 B
routerDirect.js 907 kB 907 kB ⚠️ +161 B
withRouter.js 907 kB 907 kB ⚠️ +161 B
Overall change 4.49 MB 4.49 MB ⚠️ +483 B
Commit: 1b87e5a

@kodiakhq kodiakhq bot merged commit 6ff3a63 into vercel:canary Jun 30, 2020
@Janpot Janpot deleted the trailing-slash-files branch June 30, 2020 02:29
rokinsky pushed a commit to rokinsky/next.js that referenced this pull request Jul 11, 2020
Avoid trailing slashes on urls that look like files. The redirect for `trailingSlash: true` will now look like:

```
Redirects

┌ source: /:path*/:file.:ext/
├ destination: /:path*/:file.:ext
└ permanent: true

┌ source: /:path*/:notfile([^/.]+)
├ destination: /:path*/:notfile/
└ permanent: true
```

The default still looks like:

```
Redirects

┌ source: /:path+/
├ destination: /:path+
└ permanent: true
```
After this gets merged, I have a few optimizations planned on the normalization code that should reduce the client bundle a little and that consolidates the `trailingSlash` and `exportTrailingSlash` options
@vercel vercel locked as resolved and limited conversation to collaborators Jan 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants